package com.evan.review.eventdispatch;

/**
 * Android事件分发机制详解及面试要点
 * 
 * 一、事件分发机制概述
 * 
 * 事件分发机制是Android系统处理用户触摸屏幕事件的一套流程，涉及三个核心角色：
 * 1. Activity：应用组件，包含多个View
 * 2. ViewGroup：可包含多个子View的容器
 * 3. View：最基本的UI组件
 * 
 * 当用户触摸屏幕时，系统会将触摸事件包装成MotionEvent对象，并沿着视图层次结构进行传递，决定哪个View最终处理这个事件。
 * 
 * 二、事件分发的三个核心方法
 * 
 * 1. dispatchTouchEvent(MotionEvent ev)
 *    - 作用：负责事件的分发
 *    - 调用时机：当事件传递给一个View时，该方法首先被调用
 *    - 返回值：true表示事件被消费，不再向下传递；false表示不消费，继续传递给上层View的onTouchEvent()
 * 
 * 2. onInterceptTouchEvent(MotionEvent ev)
 *    - 作用：决定是否拦截事件，仅ViewGroup有此方法
 *    - 调用时机：在ViewGroup的dispatchTouchEvent()内部调用
 *    - 返回值：true表示拦截事件，不再分发给子View；false表示不拦截，继续分发给子View
 * 
 * 3. onTouchEvent(MotionEvent ev)
 *    - 作用：处理触摸事件
 *    - 调用时机：在dispatchTouchEvent()内部调用，若没有被拦截的话
 *    - 返回值：true表示事件被消费；false表示不消费，传递给父View的onTouchEvent()
 * 
 * 三、MotionEvent对象详解
 * 
 * MotionEvent对象包含事件的类型和位置信息：
 * 
 * 1. 事件类型
 *    - ACTION_DOWN：手指刚接触屏幕（事件序列的开始）
 *    - ACTION_MOVE：手指在屏幕上移动
 *    - ACTION_UP：手指从屏幕上抬起（事件序列的结束）
 *    - ACTION_CANCEL：事件被取消（例如被上层View拦截）
 * 
 * 2. 位置信息
 *    - getX()/getY()：相对于当前View左上角的坐标
 *    - getRawX()/getRawY()：相对于屏幕左上角的坐标
 * 
 * 3. 多点触控信息
 *    - getPointerCount()：获取触摸点的数量
 *    - getPointerId(int index)：获取指定索引处的触摸点ID
 *    - findPointerIndex(int pointerId)：根据ID查找索引
 * 
 * 四、事件传递流程
 * 
 * 1. 完整传递流程
 *    Activity -> Window -> DecorView -> ViewGroup -> ... -> 子View
 * 
 * 2. 传递原则
 *    - 事件分发：自顶向下，由父View向子View传递
 *    - 事件消费：自底向上，由子View向父View传递
 *    - 责任链模式：沿着一条预设的路径依次传递，直到被消费
 * 
 * 3. 分发过程伪代码
 *    public boolean dispatchTouchEvent(MotionEvent ev) {
 *        boolean consume = false;
 *        
 *        // 1. 判断是否拦截（仅ViewGroup有此步骤）
 *        if (onInterceptTouchEvent(ev)) {
 *            // 2. 如果拦截，自己处理
 *            consume = onTouchEvent(ev);
 *        } else {
 *            // 3. 如果不拦截，传给子View处理
 *            consume = child.dispatchTouchEvent(ev);
 *        }
 *        
 *        return consume;
 *    }
 * 
 * 五、事件序列
 * 
 * 1. 事件序列定义
 *    - 一次完整的事件序列：ACTION_DOWN → 若干次ACTION_MOVE → ACTION_UP
 * 
 * 2. 事件序列传递规则
 *    - 若某个View消费了ACTION_DOWN，则同一序列的后续事件（MOVE、UP）默认传递给它
 *    - 若ACTION_DOWN事件未被消费，则同一序列的后续事件都不会再传递给该View
 *    - 一旦事件被拦截，同一序列中的后续事件将不再经过onInterceptTouchEvent()方法，而是直接交给拦截者处理
 * 
 * 3. 事件取消
 *    - 当父View决定拦截事件时，子View会收到ACTION_CANCEL事件
 *    - 收到ACTION_CANCEL后，子View应该取消所有状态，例如按下状态等
 * 
 * 六、ViewGroup和View的事件分发区别
 * 
 * 1. ViewGroup
 *    - 拥有dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()三个方法
 *    - 能够选择拦截事件或将事件传递给子View
 *    - 默认不拦截事件（onInterceptTouchEvent()返回false）
 *    - 子View可通过requestDisallowInterceptTouchEvent()请求父ViewGroup不要拦截事件
 * 
 * 2. View
 *    - 只有dispatchTouchEvent()和onTouchEvent()方法，没有onInterceptTouchEvent()
 *    - 无法向下传递事件，只能自己处理
 *    - 默认行为：可点击或可获取焦点则消费事件；否则不消费
 * 
 * 七、常见面试题
 * 
 * 1. 简述Android事件分发机制的过程？
 *    答：Android事件分发过程是一个责任链模式，从Activity开始，经过PhoneWindow, DecorView，然后自顶向下分发到
 *        ViewGroup和子View。分发过程使用dispatchTouchEvent方法，ViewGroup可通过onInterceptTouchEvent决定是否拦截，
 *        最终由onTouchEvent方法处理事件。如果子View不处理，事件会反向向上传递给父容器处理。
 * 
 * 2. 事件分发过程中的三个主要方法有什么作用和区别？
 *    答：三个方法作用不同：
 *        - dispatchTouchEvent负责分发事件，返回值表示事件是否被消费
 *        - onInterceptTouchEvent负责拦截事件（仅ViewGroup有），返回true表示拦截并自己处理
 *        - onTouchEvent负责处理事件，返回true表示消费事件，false表示不消费
 *        执行顺序：dispatchTouchEvent() -> onInterceptTouchEvent()(ViewGroup才有) -> onTouchEvent()
 * 
 * 3. View和ViewGroup对事件的处理有什么区别？
 *    答：主要区别在于ViewGroup多了onInterceptTouchEvent方法，能拦截事件并决定是自己处理还是传递给子View；
 *        View没有子View，所以没有onInterceptTouchEvent方法，只能自己处理事件。另外，ViewGroup默认不拦截事件，
 *        而View的onTouchEvent默认实现是如果可点击或可获取焦点则返回true消费事件，否则返回false。
 * 
 * 4. 事件是如何从父View传递到子View的？
 *    答：事件从父View传递到子View的过程如下：
 *        1. 父View的dispatchTouchEvent()被调用
 *        2. 父View的onInterceptTouchEvent()判断是否拦截事件
 *        3. 如果返回false不拦截，则调用子View的dispatchTouchEvent()
 *        4. 如果返回true拦截，则调用自己的onTouchEvent()处理
 *        事件传递遵循从上到下（由外向内）的分发过程。
 * 
 * 5. ACTION_DOWN事件在事件序列中的作用？
 *    答：ACTION_DOWN是事件序列的起点，具有特殊作用：
 *        1. 只有消费了ACTION_DOWN的View，才能收到后续的MOVE和UP事件
 *        2. 如果ACTION_DOWN未被消费，整个事件序列都不会再传递给该View
 *        3. ViewGroup在ACTION_DOWN时会重置触摸状态，清除之前的触摸目标
 *        4. ACTION_DOWN是决定触摸目标的关键事件
 * 
 * 6. 什么是事件冲突？如何解决？
 *    答：事件冲突是指父View和子View同时需要处理同一类触摸事件的情况。解决方法主要有：
 *        1. 外部拦截法：在父View的onInterceptTouchEvent()中根据条件决定是否拦截
 *        2. 内部拦截法：子View通过requestDisallowInterceptTouchEvent()方法，配合父View的onInterceptTouchEvent()
 *        3. 自定义处理：根据具体业务需求，通过重写相关方法自定义事件处理逻辑
 * 
 * 7. 怎样让View消费事件？
 *    答：让View消费事件有以下几种方式：
 *        1. 设置点击监听器View.setOnClickListener()
 *        2. 设置触摸监听器View.setOnTouchListener()
 *        3. 重写View的onTouchEvent()方法并返回true
 *        4. 对于ViewGroup，可以重写onInterceptTouchEvent()返回true拦截事件，然后在onTouchEvent()中消费
 * 
 * 8. 一个点击事件传递过程中，哪些方法会被调用？
 *    答：在一个典型的点击事件（从ACTION_DOWN到ACTION_UP）传递过程中：
 *        1. Activity.dispatchTouchEvent()
 *        2. Window.superDispatchTouchEvent()
 *        3. DecorView.dispatchTouchEvent()
 *        4. ViewGroup.dispatchTouchEvent()
 *        5. ViewGroup.onInterceptTouchEvent() （可能多次，取决于嵌套层级）
 *        6. View.dispatchTouchEvent()
 *        7. View.onTouchListener.onTouch() （如果设置了）
 *        8. View.onTouchEvent()
 *        9. View.performClick() （在ACTION_UP时）
 *        10. View.onClickListener.onClick() （如果设置了）
 */
public class EventDispatchDoc {
    // 这是一个文档类，只包含注释，没有实际代码
} 